#include "Bullet.h"
#include <QPainter>
#include <QDebug>
#include "Tank.h"

extern GameMap* gameMap;
extern Tank* player[4];

Bullet::Bullet(int px, int py, int _dir, QObject *parent)
{
    Q_UNUSED(parent)
    isshoot=false;
    this->pos_x=px;
    this->pos_y=py;
    this->my_dir=_dir;
    this->step = 20;
    mTank=nullptr;
    bullet=QImage(":/map_image/element/bullet.png");
}


void Bullet::BulletMove()
{
    int i;
    for(i=0;!iscollide()&&i<=HitTank();i++);
    if(i!=0)i--;
    if(my_dir == xup)
    {
        pos_y-=i;
    }
    if(my_dir == xdown)
    {
        pos_y+=i;
    }
    if(my_dir == xleft)
    {
        pos_x-=i;
    }
    if(my_dir == xright)
    {
        pos_x+=i;}

}

void Bullet::DrawBullet(QPainter* p)
{
    if(isshoot == true)
    p->drawImage(pos_x,pos_y,bullet);
}

bool Bullet::iscollide()
{
    if(HitTank()==0)
    {
        isshoot = false;
    }
    QImage mybullet(":/map_image/element/bullet.png");
    QImage mywall(":/map_image/element/wall.gif");
    int newx;
    int newy;
    int i,j;
    if(my_dir == xup)
    {
        newx = pos_x;
        newy = pos_y-step;
        for(i=0;i<gameMap->col;i++)
        {
            if(i*mywall.width()<newx && (i+1)*mywall.width()>newx+mybullet.width()) break;
        }
        if(i<gameMap->col)
        {
            for(j=0;j<gameMap->row;j++)
            {
                if((j*mywall.height()<=newy) && ((j+1)*mywall.height()>=newy+mybullet.height()))
                {
                    if(gameMap->Gmap[j][i] == wall) return true;
                }
                else if((j*mywall.height()<=newy)&& ((j+1)*mywall.height()>newy) && ((j+2)*mywall.height()>=newy+mybullet.height()))
                {
                    if(gameMap->Gmap[j][i] == wall || gameMap->Gmap[j+1][i] == wall) return true;
                }
            }
        }
        else
        {
            for(i=0;i<gameMap->col;i++)
            {
                if(newx<=i*mywall.width() && i*mywall.width()<=newx+mybullet.width()) break;
            }
            for(j=0;j<gameMap->row;j++)
            {
                if((j*mywall.height()<=newy) && ((j+1)*mywall.height()>=newy+mybullet.height()))
                {
                    if(gameMap->Gmap[j][i] == wall || gameMap->Gmap[j][i-1] == wall) return true;
                }
                else if(j*mywall.height()>=newy && ((j+1)*mywall.height()<=newy+mybullet.height()))
                {
                    if(gameMap->Gmap[j][i] == wall || gameMap->Gmap[j-1][i] == wall || gameMap->Gmap[j-1][i-1] == wall || gameMap->Gmap[j][i-1] == wall) return true;
                }
            }
        }
        return false;
    }
    else if(my_dir == xdown)
    {
        newx = pos_x;
        newy = pos_y+step;
        for(i=0;i<gameMap->col;i++)
        {
            if(i*mywall.width()<newx && (i+1)*mywall.width()>newx+mybullet.width()) break;
        }
        if(i<gameMap->col)
        {
            for(j=0;j<gameMap->row;j++)
            {
                if((j*mywall.height()<=newy) && ((j+1)*mywall.height()>=newy+mybullet.height()))
                {
                    if(gameMap->Gmap[j][i] == wall) return true;
                }
                else if((j*mywall.height()<=newy)&& ((j+1)*mywall.height()>newy) && ((j+2)*mywall.height()>=newy+mybullet.height()))
                {
                    if(gameMap->Gmap[j][i] == wall || gameMap->Gmap[j+1][i] == wall) return true;
                }
            }
        }
        else
        {
            for(i=0;i<gameMap->col;i++)
            {
                if(newx<=i*mywall.width() && i*mywall.width()<=newx+mybullet.width()) break;
            }
            for(j=0;j<gameMap->row;j++)
            {
                if((j*mywall.height()<=newy) && ((j+1)*mywall.height()>=newy+mybullet.height()))
                {
                    if(gameMap->Gmap[j][i] == wall || gameMap->Gmap[j][i-1] == wall) return true;
                }
                else if(j*mywall.height()>=newy && ((j+1)*mywall.height()<=newy+mybullet.height()))
                {
                    if(gameMap->Gmap[j][i] == wall || gameMap->Gmap[j-1][i] == wall || gameMap->Gmap[j-1][i-1] == wall || gameMap->Gmap[j][i-1] == wall) return true;
                }
            }
        }
        return false;
    }
    else if(my_dir == xleft)
    {
        newx = pos_x-step;
        newy = pos_y;
        for(i=0;i<gameMap->row;i++)
        {
            if(i*mywall.height()<newy && (i+1)*mywall.height()>newy+mybullet.height()) break;
        }
        if(i<gameMap->row)
        {
            for(j=0;j<gameMap->col;j++)
            {
                if((j*mywall.width()<=newx) && ((j+1)*mywall.width()>=newx+mybullet.width()))
                {
                    if(gameMap->Gmap[i][j] == wall) return true;
                }
                else if((j*mywall.width()<=newx)&& ((j+1)*mywall.width()>newx) && ((j+2)*mywall.width()>=newx+mybullet.width()))
                {
                    if(gameMap->Gmap[i][j] == wall || gameMap->Gmap[i][j+1] == wall) return true;
                }
            }
        }
        else
        {
            for(i=0;i<gameMap->row;i++)
            {
                if(newy<=i*mywall.height() && i*mywall.height()<=newy+mybullet.height()) break;
            }
            for(j=0;j<gameMap->col;j++)
            {
                if((j*mywall.width()<=newx) && ((j+1)*mywall.width()>=newx+mybullet.width()))
                {
                    if(gameMap->Gmap[i][j] == wall || gameMap->Gmap[i-1][j] == wall) return true;
                }
                else if((j*mywall.width()>=newx) && ((j+1)*mywall.width()<=newx+mybullet.width()))
                {
                    if(gameMap->Gmap[i][j] == wall || gameMap->Gmap[i-1][j] == wall || gameMap->Gmap[i][j-1] == wall || gameMap->Gmap[i-1][j-1] == wall) return true;
                }
            }
        }
        return false;
    }
    else if(my_dir == xright)
    {
        newx = pos_x+step;
        newy = pos_y;
        for(i=0;i<gameMap->row;i++)
        {
            if(i*mywall.height()<newy && (i+1)*mywall.height()>newy+mybullet.height()) break;
        }
        if(i<gameMap->row)
        {
            for(j=0;j<gameMap->col;j++)
            {
                if((j*mywall.width()<=newx) && ((j+1)*mywall.width()>=newx+mybullet.width()))
                {
                    if(gameMap->Gmap[i][j] == wall) return true;
                }
                else if((j*mywall.width()<=newx)&& ((j+1)*mywall.width()>newx) && ((j+2)*mywall.width()>=newx+mybullet.width()))
                {
                    if(gameMap->Gmap[i][j] == wall || gameMap->Gmap[i][j+1] == wall) return true;
                }
            }
        }
        else
        {
            for(i=0;i<gameMap->row;i++)
            {
                if(newy<=i*mywall.height() && i*mywall.height()<=newy+mybullet.height()) break;
            }
            for(j=0;j<gameMap->col;j++)
            {
                if((j*mywall.width()<=newx) && ((j+1)*mywall.width()>=newx+mybullet.width()))
                {
                    if(gameMap->Gmap[i][j] == wall || gameMap->Gmap[i-1][j] == wall) return true;
                }
                else if((j*mywall.width()>=newx) && ((j+1)*mywall.width()<=newx+mybullet.width()))
                {
                    if(gameMap->Gmap[i][j] == wall || gameMap->Gmap[i-1][j] == wall || gameMap->Gmap[i][j-1] == wall || gameMap->Gmap[i-1][j-1] == wall) return true;
                }
            }
        }
        return false;
    }
    qDebug()<<"子弹碰撞判定错误 ";
    return true;
}

int Bullet::HitTank()
{
    if(this->isshoot == false) return 0;
    int i;
    for(i=0;i<=step;i++)
    {
        int newx=pos_x;
        int newy=pos_y;
        Q_UNUSED(newx);
        Q_UNUSED(newy);
        if(my_dir == xup)
        {
            newy=pos_y-i;
        }
        if(my_dir == xdown)
        {
            newy=pos_y+i;
        }
        if(my_dir == xleft)
        {
            newx=pos_x-i;
        }
        if(my_dir == xright)
        {
            newx=pos_x+i;
        }
        for(int j=0;j<4;j++)
        {
            if((void* )player[j] != mTank && player[j]->isCreated == true)
            {
                if(player[j]->pos_x<newx && player[j]->pos_x+player[j]->tank.width()>newx && player[j]->pos_y<newy && player[j]->pos_y+player[j]->tank.height()>newy)
                {
                    qDebug()<<"子弹打到坦克了"<<player[j]->HP;
                    //player[j]->HP-=5;
                    player[j]->isCreated=false;
                    this->isshoot=false;
                    return i;
                }
                if(player[j]->pos_x<newx && player[j]->pos_x+player[j]->tank.width()>newx && player[j]->pos_y<newy+bullet.height() && player[j]->pos_y+player[j]->tank.height()>newy+bullet.height())
                {
                    qDebug()<<"子弹打到坦克了"<<player[j]->HP;
                    //player[j]->HP-=5;
                    player[j]->isCreated=false;
                    this->isshoot=false;
                    return i;
                }
                if(player[j]->pos_x<newx+bullet.width() && player[j]->pos_x+player[j]->tank.width()>newx+bullet.width() && player[j]->pos_y<newy && player[j]->pos_y+player[j]->tank.height()>newy)
                {
                    qDebug()<<"子弹打到坦克了"<<player[j]->HP;
                    //player[j]->HP-=5;
                    player[j]->isCreated=false;
                    this->isshoot=false;
                    return i;
                }
                if(player[j]->pos_x<newx+bullet.width() && player[j]->pos_x+player[j]->tank.width()>newx+bullet.width() && player[j]->pos_y<newy+bullet.height() && player[j]->pos_y+player[j]->tank.height()>newy+bullet.height())
                {
                    qDebug()<<"子弹打到坦克了"<<player[j]->HP;
                    //player[j]->HP-=5;
                    player[j]->isCreated=false;
                    this->isshoot=false;
                    return i;
                }
                qDebug()<<"子弹没有打到坦克";
            }
        }
    }
    return step;
}

void Bullet::setTank(void *p)
{
    mTank=p;
}
